﻿using System;
using System.Reflection;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.WindowsMobile.Samples.Location;
using KMLCreator;
using Mirkuz.Mapping;
using Mirkuz.PowerManagement;

namespace Mirkuz.TrailCompanion
{
    public partial class fMain : Form
    {          

        UnattendedManager _uman = new UnattendedManager();

        GPSManager _gps;
        
        DateTime _lastfix=DateTime.Now;

        public static MapPoint CurrentPosition;
        public static TrailManager Trail = new TrailManager();
        public static WaypointManager Wpmgr = new WaypointManager();
        public static SettingDataSet settingDataSet1;

        bool _gps_ok = false;

        fGPSStat fGPS = null;

        delegate void SimpleDelegate();

        string SettingsFileName = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "/mkrunner.xml";
        string KMLFileName =Environment.GetFolderPath(Environment.SpecialFolder.Personal) + "/TC-" + DateTime.Now.ToString("yyyy-MM-dd-hh-mm") +".kml";
        string GMMExeFile = "/program files/googlemaps/googlemaps.exe";

        public fMain()
        {
            InitializeComponent();
        }

        private void fMain_Load(object sender, EventArgs e)
        {
            lblVersion.Text = " V:" + Assembly.GetExecutingAssembly().GetName().Version.ToString(4);

            settingDataSet1 = new Mirkuz.TrailCompanion.SettingDataSet();
            settingDataSet1.DataSetName = "SettingDataSet";
            settingDataSet1.SchemaSerializationMode = System.Data.SchemaSerializationMode.IncludeSchema;
            //carico valori target
            try
            {
                settingDataSet1.ReadXml(SettingsFileName);
            }
            catch
            {
                settingDataSet1.Settings.AddSettingsRow(60,true);
                settingDataSet1.WriteXml(SettingsFileName);
            }

            _gps = new GPSManager();
            _gps.NewFixAvailable += new EventHandler(_gps_NewFixAvailable);
            _gps.DifficultReception += new EventHandler(_gps_DifficultReception);
            _gps.PollingSeconds = 60;
            _gps.Start();
        
        }
        private void fMain_Closed(object sender, EventArgs e)
        {
            _gps.Stop();

            _gps = null;

            if (Trail.IsRunning)
                Trail.Stop();

            _uman.Dispose();

        }

        #region gpsevents
        void _gps_DifficultReception(object sender, EventArgs e)
        {
            Invoke(new SimpleDelegate(DifficultReception));
        }

        void _gps_NewFixAvailable(object sender, EventArgs e)
        {
            CurrentPosition = MapPoint.FromGPSPosition(_gps.CurrentPosition);
            Invoke(new SimpleDelegate(UpdateData));
        }

        private void UpdateData()
        {
            _lastfix = DateTime.Now;

            UpdateGPSUI();

            lblDIstanceToTarget.Text = "-";
            lblAltitudeToTarget.Text = "-";
            lblTarget.Text = "-";

            if (Trail.IsRunning && CurrentPosition != null)
                Trail.UpdatePosition(CurrentPosition);
            
            lblDistance.Text = Trail.RunningDistance.ToString("N0") + " m";

            if (Trail.TargetWaypoint != null)
            {
                lblTarget.Text = Trail.TargetWaypoint.Name;
                lblDIstanceToTarget.Text = Trail.DistanceToTargetWaypoint.ToString("N0") + " m";
                lblAltitudeToTarget.Text = Trail.AltitudeToTargetWaypoint.ToString("N0") + " mslm";
            }
        }

        private void UpdateGPSUI()
        {
            /*controlli form principale*/
            _gps_ok = false;
            lblGPSFront.ForeColor = Color.Red;

            if (_gps.CurrentPosition != null)            
            {
                lblSpeed.Text = (_gps.CurrentPosition.Speed * 1.852).ToString("N1") + " Km/h";
                lblAltitude.Text = _gps.CurrentPosition.SeaLevelAltitude.ToString("N0") + " mslm";
                lblGPSFront.ForeColor = Color.LimeGreen;

                if (_gps.CurrentPosition.HeadingValid)
                {
                    try
                    {
                        int i = (int)(_gps.CurrentPosition.Heading / 22.5f);
                        string[] headings ={"N","N-NE","NE","E-NE","E","E-SE","SE","S-SE",
                                      "S","S-SO","SO","O-SO","O","O-NO","NO","N-NO","N"};

                        lblCurHeading.Text = headings[i]
                            + " (" + _gps.CurrentPosition.Heading.ToString("N1") + "°)";
                    }
                    catch { lblCurHeading.Text = "N/A"; }
                }
                else
                    lblCurHeading.Text = "N/A";

                _gps_ok = true;             
            }

            /*controlli gps dettagliati*/
            if (fGPS != null)
                fGPS.UpdateData(_gps.CurrentPosition);
        }

        private void DifficultReception()
        {
            lblGPSFront.ForeColor = Color.Red;
            _gps_ok = false;
        }

        #endregion
       
        private void cmdStart_Click(object sender, EventArgs e)
        {
            if (Trail.IsRunning)
            {
                tmrAutoSave.Enabled = false;

                //fermo il Trail e salvo i dati
                Trail.Stop();

                _uman.ReleaseUnattendedMode();

                KMLFileName =Environment.GetFolderPath(Environment.SpecialFolder.Personal) +  "/TC-" + DateTime.Now.ToString("yyyy-MM-dd-hh-mm") +".kml";

                Trail.SaveTrail(KMLFileName);
                mnuGmaps.Enabled = true;

                cmdStart.Text = "Start Session";

            }
            else
            {
                if (!_gps_ok)
                {
                    MessageBox.Show("No GPS Fix", "TrailCompanion", MessageBoxButtons.OK, MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button1);
                    return;
                }
                
                //avvio il Trail
                Trail.Start(CurrentPosition);
                
                cmdStart.Text = "End Session";

                _uman.RequestUnattendedMode();

                tmrAutoSave.Enabled = settingDataSet1.Settings[0].AutosaveEnabled;
            }
        }

        #region timers
        private void tmrUpdateData_Tick(object sender, EventArgs e)
        {
            try
            {
                if (_uman.SystemState == SystemStates.On || _uman.SystemState == SystemStates.Unknown)
                    _gps.PollingSeconds = 10;
                else
                    _gps.PollingSeconds = settingDataSet1.Settings[0].GPSPolling;

                lblGPSFront.Text = "GPS " + DateTime.Now.Subtract(_lastfix).TotalSeconds.ToString() + "s ago";
             
                Trail.Tick();

                lblTime.Text = Trail.ElapsedTime.Hours.ToString("00") + ":"
                                + Trail.ElapsedTime.Minutes.ToString("00") + ":"
                                + Trail.ElapsedTime.Seconds.ToString("00");               
            }
            catch { }
        }
        private void tmrAutoSave_Tick(object sender, EventArgs e)
        {
            Trail.SaveTrail(KMLFileName);
            mnuGmaps.Enabled = true;
        }
        #endregion
                
        #region menu
        private void mnuQuit_Click(object sender, EventArgs e)
        {
            if (!Trail.IsRunning)
            {
                this.Close();
            }
        }

        private void mnuLock_Click(object sender, EventArgs e)
        {
            VKeyManager.LockKeypad();
        }

        private void mnuGPS_Click(object sender, EventArgs e)
        {
            if (fGPS == null)
            {
                fGPS = new fGPSStat();
                UpdateGPSUI();
                fGPS.ShowDialog();
                fGPS.Dispose();
                fGPS = null;
            }
        }        

        private void mnuWaypoints_Click(object sender, EventArgs e)
        {
            fWaypoints f = new fWaypoints();
            f.ShowDialog();
            f = null;
        }

        private void mnuMap_Click(object sender, EventArgs e)
        {
            try
            {
                fMap f = new fMap(Trail.Track);
                f.ShowDialog();
                f.Dispose();
                f = null;
            }
            catch { }
        }
        private void mnuSettings_Click(object sender, EventArgs e)
        {
            try
            {
                fSettings f = new fSettings();
                if (f.ShowDialog() == DialogResult.OK)
                {                    //salvataggio settings
                    settingDataSet1.Settings[0].GPSPolling = (int)f.nmPolling.Value;
                    settingDataSet1.Settings[0].AutosaveEnabled = f.rdEnableAutosave.Checked;
                    tmrAutoSave.Enabled = settingDataSet1.Settings[0].AutosaveEnabled;
                    settingDataSet1.WriteXml(SettingsFileName);
                }

                f.Dispose();
                f = null;
            }
            catch { }
        }
        #endregion   

        private void mnuGmaps_Click(object sender, EventArgs e)
        {            
            if (System.IO.File.Exists(KMLFileName))
                if (System.IO.File.Exists(GMMExeFile))
                    try
                    {
                        System.Diagnostics.Process.Start(KMLFileName,"");
                    }
                    catch (Exception ex) {
                        MessageBox.Show("Error while launching GoogleMaps", "TrailCompanion", MessageBoxButtons.OK, MessageBoxIcon.Asterisk,MessageBoxDefaultButton.Button1);
                    }
        }

    }
}